// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <memory>

#include <pollux/dwio/common/file_sink.h>
#include <pollux/dwio/common/options.h>
#include <pollux/dwio/common/writer.h>

namespace kumo::pollux::dwio::common {
    /// Writer factory interface.
    ///
    /// Implement this interface to provide a factory of writers
    /// for a particular file format. Factory objects should be
    /// registered using registerWriteFactory method to become
    /// available for connectors. Only a single writer factory
    /// per file format is allowed.
    class WriterFactory {
    public:
        /// Constructor.
        /// @param format File format this factory is designated to.
        explicit WriterFactory(FileFormat format) : format_(format) {
        }

        virtual ~WriterFactory() = default;

        /// Get the file format ths factory is designated to.
        FileFormat fileFormat() const {
            return format_;
        }

        /// Create a writer object.
        /// @param sink output sink
        /// @param options writer options
        /// @return writer object
        virtual std::unique_ptr<Writer> createWriter(
            std::unique_ptr<dwio::common::FileSink> sink,
            const std::shared_ptr<dwio::common::WriterOptions> &options) = 0;

        /// Creates a polymorphic writer options object.
        virtual std::unique_ptr<dwio::common::WriterOptions>
        createWriterOptions() = 0;

    private:
        const FileFormat format_;
    };

    /// Register a writer factory. Only a single factory can be registered
    /// for each file format. An attempt to register multiple factories for
    /// a single file format would cause a failure.
    // @return true
    bool registerWriterFactory(std::shared_ptr<WriterFactory> factory);

    /// Unregister a writer factory for a specified file format.
    /// @return true for unregistered factory and false for a
    /// missing factory for the specified format.
    bool unregisterWriterFactory(FileFormat format);

    /// Get writer factory object for a specified file format. Results in
    /// a failure if there is no registered factory for this format.
    /// @return WriterFactory object
    std::shared_ptr<WriterFactory> getWriterFactory(FileFormat format);

    /// Check if a writer factory object exists for a specified file format.
    /// Returns true if there is a registered factory for this format, false
    /// otherwise.
    /// @return true
    bool hasWriterFactory(FileFormat format);
} // namespace kumo::pollux::dwio::common
